#include "stdafx.h"
#include "Connection.h"

#ifdef _WIN32
#ifdef _DEBUG
	#define _CRTDBG_MAP_ALLOC
	#include <stdlib.h>
	#include <crtdbg.h>
	#undef THIS_FILE
	static char THIS_FILE[] = __FILE__;
	#define new       new( _NORMAL_BLOCK, __FILE__, __LINE__)
	#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif


namespace tlnet {

// Constructor
Connection::Connection(HANDLE mutex, HANDLE hReady) {
	this->mutex = mutex;	// not used here, only used by the BufferManager
	this->hReady = hReady;	// used to signal there is data available
	this->socket = NULL;
	this->thread = NULL;

	this->bm = new BufferManager(mutex);
	
	this->prev = this->next = NULL;
}

// Deconstructor
Connection::~Connection() {
	DWORD lpExitCode;

	// waits up till the linger amount for buffers to empty
//	printf("shutdown\n");
	shutdown(socket, SD_SEND);

	// wait for thread to finish, if it hasn't already
	printf("waiting for thread to finish\n");
	GetExitCodeThread((HANDLE)thread, &lpExitCode);
	while(lpExitCode == STILL_ACTIVE) {
		WaitForSingleObject((HANDLE)thread, 200);
		GetExitCodeThread((HANDLE)thread, &lpExitCode);
//		printf(".");
	}

	// Close the thread handle
	printf("closing thread handle\n");
	CloseHandle((HANDLE)thread);

	// now that buffers have emptied, close the socket
	printf("closing socket\n");
	closesocket(socket);

	delete this->bm;
}


bool Connection::set(char *data, char *value) {
	return this->settings.set(data, value);
}

char* Connection::get(char *data) {
	return this->settings.get(data);
}

bool Connection::del(char *data) {
	return this->settings.del(data);
}


// returns a pointer to the current available string,
// or NULL if none is available
char* Connection::getData() {
	return this->bm->getNext();
}


// removes current available string
void Connection::pop() {
	this->bm->pop();
}


// keeps the current available string saved & available at next eol
void Connection::push() {
	this->bm->push();
}


// write data to the socket
bool Connection::write(char *bytes) {
	return this->write(bytes, strlen(bytes));
}

// write data to the socket
bool Connection::write(char *bytes, int count) {
#ifdef _DEBUG
/*
	char *data = new char[count + 5 + strlen("[] Send: ") + 1];	// 5 for len of socket integer

	sprintf(data, "[%d] Send: %s", this->socket, bytes);
	printf(data);

	delete[] data;
*/
#endif /* _DEBUG */

	if(send(this->socket, bytes, count, 0) == -1) {
		 return false;
	}

	return true;
}

}